﻿using System;
using System.Linq;
using Common; //Common contains all the classes you need to play CloudBall.

namespace TeamOne
{
    /// <summary>
    /// WildCat01
    /// </summary>
    public class TeamOne : ITeam                              
    {
		private const int SimTurns = 0x4b;

		public bool FreeMove(IPosition from, IPosition to, Team t)
		{
			IPosition position = from.Position + ((Vector)(((to.Position - from.Position) / from.Position.GetDistanceTo(to)) * Constants.PlayerMaxVelocity));
			foreach (Player player in t.Players)
			{
				IPosition position2 = player.Position + ((Vector)(((position.Position - player.Position) / player.Position.GetDistanceTo(position)) * Constants.PlayerMaxVelocity));
				if ((player.TackleTimer < 2) && (position2.Position.GetDistanceTo(position) <= Constants.PlayerMaxTackleDistance))
				{
					return false;
				}
			}
			return true;
		}

		public bool TryShoot(IPosition pos, Ball ball, Team t1, Team t2)
		{
			Vector[] bP = new Vector[75];
			bP[0] = ball.Position;
			Vector vector = (Vector)(((pos.Position - ball.Position) / pos.GetDistanceTo(ball)) * Constants.BallMaxVelocity);
			int num = 75;
			for (int i = 1; i < 75; i++)
			{
				bP[i] = bP[i - 1] + vector;
				if (bP[i].X > Field.Borders.Width)
				{
					if ((bP[i].Y > Field.EnemyGoal.Top.Y) && (bP[i].Y < Field.EnemyGoal.Bottom.Y))
					{
						num = i;
						break;
					}
					bP[i].X = (2f * Field.Borders.Width) - bP[i].X;
				}
				if (bP[i].X < 0f)
				{
					bP[i].X = -bP[i].X;
				}
				if (bP[i].Y < 0f)
				{
					bP[i].Y = -bP[i].Y;
				}
				if (bP[i].Y > Field.Borders.Height)
				{
					bP[i].Y = (2f * Field.Borders.Height) - bP[i].Y;
				}
				vector = (Vector)(vector * Constants.BallSlowDownFactor);
			}
			int num3 = 75;
			int num4 = 75;
			foreach (Player player in t1.Players)
			{
				int num5 = this.TurnsToGetBall(player, ball, bP, 1f);
				if (num5 < num3)
				{
					num3 = num5;
				}
			}
			foreach (Player player2 in t2.Players)
			{
				int num6 = this.TurnsToGetBall(player2, ball, bP, 1.025f);
				if (num6 < num4)
				{
					num4 = num6;
				}
			}
			if (num3 >= num4)
			{
				return (num < num4);
			}
			return true;
		}

		public int TurnsToGetBall(Player p, Ball ball, Vector[] BP, float mul)
		{
			if (ball.Owner != p)
			{
				float ballMaxPickUpDistance = Constants.BallMaxPickUpDistance;
				for (int i = 1; i < 75; i++)
				{
					if ((BP[i].Position.GetDistanceTo(p.Position) - (Constants.PlayerMaxVelocity * i)) < ballMaxPickUpDistance)
					{
						return i;
					}
					ballMaxPickUpDistance *= mul;
				}
			}
			return 74;
		}



 


		public void Action(Team myTeam, Team enemyTeam, Ball ball, MatchInfo matchInfo)
		{
			foreach (Player player in myTeam.Players.Where(player => (ball.Owner == player) || player.CanPickUpBall(ball)))
			{
			    if (ball.Owner != player)
			    {
			        player.ActionPickUpBall();
			        return;
			    }
			    if (this.TryShoot(Field.EnemyGoal.Center, ball, myTeam, enemyTeam))
			    {
			        player.ActionShoot(Field.EnemyGoal.Center);
			        return;
			    }
			    if (this.TryShoot(Field.EnemyGoal.Top + new Vector(0f, 25f), ball, myTeam, enemyTeam))
			    {
			        player.ActionShoot(Field.EnemyGoal.Top + new Vector(0f, 25f));
			        return;
			    }
			    if (this.TryShoot(Field.EnemyGoal.Bottom - new Vector(0f, 25f), ball, myTeam, enemyTeam))
			    {
			        player.ActionShoot(Field.EnemyGoal.Bottom - new Vector(0f, 25f));
			        return;
			    }
			    Player player2 = null;
			    float distanceTo = player.Position.GetDistanceTo(Field.EnemyGoal.Center);
			    foreach (Player player3 in myTeam.Players)
			    {
			        if ((!(player == player3) && this.TryShoot(player3.Position, ball, myTeam, enemyTeam)) && (player3.Position.GetDistanceTo(Field.EnemyGoal.Center) < distanceTo))
			        {
			            distanceTo = player3.Position.GetDistanceTo(Field.EnemyGoal.Center);
			            player2 = player3;
			        }
			    }
			    if (player2 != null)
			    {
			        player.ActionShoot(player2.Position, 7f);
			    }
			    else
			    {
			        bool flag = this.FreeMove(player.Position, Field.EnemyGoal.Center, enemyTeam);
			        foreach (Player player4 in enemyTeam.Players)
			        {
			            if ((player4.Position.GetDistanceTo(player.Position) <= Constants.PlayerMaxTackleDistance) || !flag)
			            {
			                player2 = null;
			                distanceTo = Field.Borders.Width * 2f;
			                foreach (Player player5 in myTeam.Players)
			                {
			                    if ((!(player == player5) && this.TryShoot(player5.Position, ball, myTeam, enemyTeam)) && (player5.Position.GetDistanceTo(Field.EnemyGoal.Center) < distanceTo))
			                    {
			                        distanceTo = player5.Position.GetDistanceTo(Field.EnemyGoal.Center);
			                        player2 = player5;
			                    }
			                }
			                if (player2 != null)
			                {
			                    player.ActionShoot(player2.Position, 7f);
			                }
			                break;
			            }
			        }
			    }
			    if (player2 == null)
			    {
			        player.ActionGo(Field.EnemyGoal.Center);
			    }
			    foreach (Player player6 in myTeam.Players)
			    {
			        if (player6 != player)
			        {
			            Player closest = player6.GetClosest(enemyTeam);
			            if (player6.CanTackle(closest))
			            {
			                player6.ActionTackle(closest);
			            }
			            else
			            {
			                if (player6.PlayerType == PlayerType.Keeper)
			                {
			                    player6.ActionGo(new Vector(ball.Position.X / 4f, (ball.Position.Y + Field.Borders.Center.Y) / 2f));
			                    continue;
			                }
			                if (player6.PlayerType == PlayerType.LeftDefender)
			                {
			                    player6.ActionGo(new Vector(ball.Position.X * 0.65, (double)(ball.Position.Y / 2f)));
			                    continue;
			                }
			                if (player6.PlayerType == PlayerType.RightDefender)
			                {
			                    player6.ActionGo(new Vector(ball.Position.X * 0.65, (double)((ball.Position.Y + Field.Borders.Bottom.Y) / 2f)));
			                    continue;
			                }
			                if (player6.PlayerType == PlayerType.LeftForward)
			                {
			                    player6.ActionGo(new Vector((ball.Position.X + Field.Borders.Width) / 2f, ball.Position.Y / 2f));
			                    continue;
			                }
			                if (player6.PlayerType == PlayerType.RightForward)
			                {
			                    player6.ActionGo(new Vector((ball.Position.X + Field.Borders.Width) / 2f, (ball.Position.Y + Field.Borders.Height) / 2f));
			                    continue;
			                }
			                if (player6.PlayerType == PlayerType.CenterForward)
			                {
			                    player6.ActionGo(new Vector((ball.Position.X + Field.Borders.Width) / 2f, (ball.Position.Y + Field.Borders.Center.Y) / 2f));
			                }
			            }
			        }
			    }
			    return;
			}
			foreach (Player player8 in enemyTeam.Players)
			{
			    if ((ball.Owner != player8) && !player8.CanPickUpBall(ball)) continue;
			    Player player9 = null;
			    float num2 = Field.Borders.Width * 2f;
			    foreach (Player player10 in myTeam.Players
                    .Where(player10 => 
                        ((player10.PlayerType != PlayerType.Keeper) && (player10.Position.X < ball.Position.X)) && (player10.Position.GetDistanceTo(ball) < num2)))
			    {
			        player9 = player10;
			        num2 = player10.Position.GetDistanceTo(ball);
			    }
			    float width = Field.Borders.Width;
			    Player player11 = null;
			    foreach (Player player12 in myTeam.Players)
			    {
			        if (((player12.PlayerType != PlayerType.Keeper) && (player12.Position.X < ball.Position.X)) && (width > player8.Position.X))
			        {
			            width = player8.Position.X;
			        }
			        Player target = player12.GetClosest(enemyTeam);
			        if (player12.CanTackle(target))
			        {
			            player12.ActionTackle(target);
			            continue;
			        }
			        if (player12 == player9)
			        {
			            if (width > player12.Position.X)
			            {
			                width = player12.Position.X;
			            }
			            player12.ActionGo(new Vector(ball.Position.X - (Math.Abs((float)(ball.Position.Y - player12.Position.Y)) / 2f), ball.Position.Y));
			            continue;
			        }
			        if (player12.PlayerType == PlayerType.Keeper)
			        {
			            player11 = player12;
			        }
			        else
			        {
			            if (player12.PlayerType == PlayerType.LeftDefender)
			            {
			                player12.ActionGo(new Vector((double)(ball.Position.X / 2f), ball.Position.Y * 0.75));
			                continue;
			            }
			            if (player12.PlayerType == PlayerType.RightDefender)
			            {
			                player12.ActionGo(new Vector((double)(ball.Position.X / 2f), (ball.Position.Y * 0.75) + (Field.Borders.Height * 0.25)));
			                continue;
			            }
			            if (player12.PlayerType == PlayerType.LeftForward)
			            {
			                player12.ActionGo(new Vector(ball.Position.X * 0.67, (double)(ball.Position.Y / 2f)));
			                continue;
			            }
			            if (player12.PlayerType == PlayerType.RightForward)
			            {
			                player12.ActionGo(new Vector(ball.Position.X * 0.67, (double)((ball.Position.Y + Field.Borders.Height) / 2f)));
			                continue;
			            }
			            if (player12.PlayerType == PlayerType.CenterForward)
			            {
			                player12.ActionGo(new Vector(ball.Position.X * 0.67, (double)((ball.Position.Y + Field.Borders.Center.Y) / 2f)));
			            }
			        }
			    }
			    if (player11 != null)
			    {
			        if (width == Field.Borders.Width)
			        {
			            player11.ActionGo(new Vector(ball.Position.X, ball.Position.Y));
			        }
			        else
			        {
			            player11.ActionGo((Vector)((ball.Position * 0.3) + (Field.MyGoal.Center * 0.7)));
			        }
			    }
			    return;
			}
			Vector[] bP = new Vector[0x4b];
			bP[0] = ball.Position;
			Vector velocity = ball.Velocity;
			for (int i = 1; i < 75; i++)
			{
				bP[i] = bP[i - 1] + velocity;
				velocity = velocity * Constants.BallSlowDownFactor;
			}
			int index = 75;
			int num6 = 75;
			Player player14 = null;
			foreach (Player player15 in myTeam.Players)
			{
				int num7 = this.TurnsToGetBall(player15, ball, bP, 1f);
				if (num7 < index)
				{
					index = num7;
					player14 = player15;
				}
			}
			foreach (Player player16 in enemyTeam.Players)
			{
				int num8 = this.TurnsToGetBall(player16, ball, bP, 1f);
				if (num8 < num6)
				{
					num6 = num8;
				}
			}
			if (index <= num6)
			{
				foreach (Player player17 in myTeam.Players)
				{
					Player player18 = player17.GetClosest(enemyTeam);
					if (player17.CanTackle(player18))
					{
						player17.ActionTackle(player18);
					}
					else
					{
						if (player17 == player14)
						{
							player17.ActionGo(bP[index]);
							continue;
						}
						if (player17.PlayerType == PlayerType.Keeper)
						{
							player17.ActionGo(new Vector(bP[index].X / 4f, (bP[index].Y + Field.Borders.Center.Y) / 2f));
							continue;
						}
						if (player17.PlayerType == PlayerType.LeftDefender)
						{
							player17.ActionGo(new Vector(0.65 * bP[index].X, (double)(bP[index].Y / 2f)));
							continue;
						}
						if (player17.PlayerType == PlayerType.RightDefender)
						{
							player17.ActionGo(new Vector(0.65 * bP[index].X, (double)((bP[index].Y + Field.Borders.Height) / 2f)));
							continue;
						}
						if (player17.PlayerType == PlayerType.LeftForward)
						{
							player17.ActionGo(new Vector((bP[index].X + Field.Borders.Width) / 2f, bP[index].Y / 2f));
							continue;
						}
						if (player17.PlayerType == PlayerType.RightForward)
						{
							player17.ActionGo(new Vector((bP[index].X + Field.Borders.Width) / 2f, (bP[index].Y + Field.Borders.Height) / 2f));
							continue;
						}
						if (player17.PlayerType == PlayerType.CenterForward)
						{
							player17.ActionGo(new Vector((bP[index].X + Field.Borders.Width) / 2f, (bP[index].Y + Field.Borders.Center.Y) / 2f));
						}
					}
				}
			}
			else
			{
				Player player19 = null;
				float num9 = Field.Borders.Width * 2f;
				foreach (Player player20 in myTeam.Players)
				{
					if (((player20.PlayerType != PlayerType.Keeper) && (player20.Position.X < ball.Position.X)) && (player20.Position.GetDistanceTo(ball) < num9))
					{
						player19 = player20;
						num9 = player20.Position.GetDistanceTo(ball);
					}
				}
				float x = Field.Borders.Width;
				Player player21 = null;
				foreach (Player player22 in myTeam.Players)
				{
					if ((player22.PlayerType != PlayerType.Keeper) && (x > player22.Position.X))
					{
						x = player22.Position.X;
					}
					Player player23 = player22.GetClosest(enemyTeam);
					if (player22.CanTackle(player23))
					{
						player22.ActionTackle(player23);
						continue;
					}
					if (player22 == player19)
					{
						if (x > player22.Position.X)
						{
							x = player22.Position.X;
						}
						float num11 = player22.Position.GetDistanceTo(bP[num6]) / Constants.PlayerMaxVelocity;
						player22.ActionGo(new Vector(bP[num6].X - (Constants.PlayerMaxVelocity * (num6 - num11)), bP[num6].Y));
						continue;
					}
					if (player22.PlayerType == PlayerType.Keeper)
					{
						player22.ActionGo(new Vector(bP[index].X - 10f, bP[index].Y));
					}
					else
					{
						if (player22.PlayerType == PlayerType.LeftDefender)
						{
							player22.ActionGo(new Vector((double)(bP[index].X / 2f), bP[index].Y * 0.75));
							continue;
						}
						if (player22.PlayerType == PlayerType.RightDefender)
						{
							player22.ActionGo(new Vector((double)(bP[index].X / 2f), (bP[index].Y * 0.75) + (Field.Borders.Height * 0.25)));
							continue;
						}
						if (player22.PlayerType == PlayerType.LeftForward)
						{
							player22.ActionGo(new Vector(bP[index].X * 0.67, (double)(bP[index].Y / 2f)));
							continue;
						}
						if (player22.PlayerType == PlayerType.RightForward)
						{
							player22.ActionGo(new Vector(bP[index].X * 0.67, (double)((bP[index].Y + Field.Borders.Height) / 2f)));
							continue;
						}
						if (player22.PlayerType == PlayerType.CenterForward)
						{
							player22.ActionGo(new Vector(bP[index].X * 0.67, (double)((bP[index].Y + Field.Borders.Center.Y) / 2f)));
						}
					}
				}
				if ((x < Field.Borders.Width) && (player21 != null))
				{
					player21.ActionGo(new Vector(bP[index].X - 10f, bP[index].Y));
				}
			}
		}
    }
}